# app/api/endpoints.py

from fastapi import APIRouter, Depends, Request, HTTPException, Query,FastAPI, Body
from fastapi.responses import JSONResponse
import asyncio
from datetime import datetime, timedelta
import time
import logging
from datetime import datetime 
from sqlalchemy.orm import Session
from app.services.oss_service import get_sts_token
from app.db.session import get_db
from app.models.models import User, Job, Voice, Video, JobV2
from app.services.external_api import (
    forward_request_to_external_api,
    create_voice,
    train_voice,
    confirm_voice,
    list_voices 
)
from app.services.taskss import TaskManager
from app.utils.validation import Validator
from pydantic import BaseModel
from typing import Optional, List
from app.services.huoshan_oss import huoshan_oss_token
from app.utils.youshuai import ApiClient
from app.core.config import settings
from sqlalchemy.orm import joinedload

router = APIRouter()

task_manager = TaskManager()

youshu_ai = ApiClient() 

# 火山OSS临时秘钥
@router.post("/huoshan_oss_token")
def huoshan_post_oss_token():
    try:
        oss_token = huoshan_oss_token()
        return JSONResponse(status_code=200,content = {'code': 200, 'message':oss_token})
    except Exception as e:
        logging.error(f"Error creating oss_token: {e}")
        return JSONResponse(status_code=500, content={'error': 'Internal server error'})

# 创建用户
@router.post("/user/create")
async def create_user(user_data: dict, db: Session = Depends(get_db)):
    try:
        name_id = user_data.get('name_id')
        if not name_id:
            return JSONResponse(status_code=400, content={'error': 'name_id is required'})
        if db.query(User).filter(User.name_id == name_id).first():
            return JSONResponse(status_code=400, content={'error': 'User already exists'})

        new_user = User(name_id=name_id)
        db.add(new_user)
        db.commit()
        logging.info(f"Created new user with name_id={name_id}")
        return JSONResponse(status_code=200, content={'code': 200, 'message': 'User created successfully'})
    except Exception as e:
        logging.error(f"Error creating user: {e}")
        db.rollback()
        return JSONResponse(status_code=500, content={'error': 'Internal server error'})

# 创建任务（V1接口，后台转发到V2处理）
@router.post("/task/create")
async def create_task(request: Request, db: Session = Depends(get_db)):
    logging.info(f"收到V1任务创建请求，自动转发到V2处理：{request.method} {request.url.path}")

    # 导入V2的处理函数
    from app.api.endpoints_v2 import create_videomix_v2_endpoint
    
    try:
        # 直接调用V2的处理函数
        return await create_videomix_v2_endpoint(request, db)
    except Exception as e:
        logging.error(f"V1转发到V2处理时出错：{e}")
        return JSONResponse(status_code=500, content={'error': 'Internal server error'})

# 声音训练（V1接口，后台转发到V2处理）
@router.post("/voice/train")
async def train_voice_handler(request: Request, db: Session = Depends(get_db)):
    logging.info(f"收到V1声音训练请求，自动转发到V2处理：{request.method} {request.url.path}")

    # 导入V2的处理函数
    from app.api.endpoints_v2 import create_voice_clone_v2_endpoint
    
    try:
        # 直接调用V2的处理函数
        return await create_voice_clone_v2_endpoint(request, db)
    except Exception as e:
        logging.error(f"V1转发到V2处理时出错：{e}")
        return JSONResponse(status_code=500, content={'error': 'Internal server error'})

# 创建数字人接口（V1接口，后台转发到V2处理）
@router.post("/video/create")
async def create_digital_human(request: Request, db: Session = Depends(get_db)):
    logging.info(f"收到V1数字人创建请求，自动转发到V2处理：{request.method} {request.url.path}")

    # 导入V2的处理函数
    from app.api.endpoints_v2 import create_digital_human_v2_endpoint
    
    try:
        # 直接调用V2的处理函数
        return await create_digital_human_v2_endpoint(request, db)
    except Exception as e:
        logging.error(f"V1转发到V2处理时出错：{e}")
        return JSONResponse(status_code=500, content={'error': 'Internal server error'})

# 查询指定用户信息的接口
@router.get("/user/content")
async def get_user_content(
    name_id: str = Query(..., description="User's name_id"),
    type: int = Query(..., description="Query type: 1 for digital human, 2 for voices, 3 for jobs, 4 for V2 jobs only"),
    db: Session = Depends(get_db)
):
    try:
        if not name_id or type not in [1, 2, 3, 4]:
            return JSONResponse(status_code=400, content={'error': 'Invalid parameters'})

        if type == 1:
            # 查询 Video 表
            contents = db.query(Video).filter(Video.name_id == name_id).all()
            result = [
                {
                    'name_id': c.name_id,
                    'id': c.id,
                    'video_url': c.video_url,
                    'title': c.title,
                    'time': c.time
                } for c in contents
            ]
            return JSONResponse(status_code=200, content={'code': 200, 'type': 1, 'data': result})

        elif type == 2:
            # 如果 name_id 为 '-1'，从外部 API 获取声音列表，并过滤 type=10 的数据
            if name_id == '-1':
                try:
                    # 调用外部 API 获取声音列表
                    # response_data, status_code = await list_voices()
                    
                    # 假设 API 调用成功并返回有效数据
                    # if status_code == 200 and response_data.get('code') == 0:
                    #     filtered_data = [
                    #         {
                    #             'voice_id': item['voice_id'],
                    #             'type': item['type'],
                    #             'title': item['title']
                    #         }
                    #         for item in response_data.get('data', [])
                    #         if item.get('type') == 10
                    #     ]
                    result = settings.GONGGONG_AUDIO_URL
                    return JSONResponse(
                        status_code=200,
                        content=result
                    )
                    # else:
                    #     logging.error(f"外部API返回错误，status_code={status_code}, response_data={response_data}")
                    #     raise ValueError("Failed to retrieve voice list from external API")
                except Exception as e:
                    logging.error(f"调用外部 API 获取声音列表失败: {e}")
                    return JSONResponse(
                        status_code=500,
                        content={'error': 'Failed to retrieve voice list from external API'}
                    )
            else:
                # 从本地 voices 表查询用户的声音数据
                try:
                    contents = db.query(Voice).filter(Voice.name_id == name_id).all()
                    result = []
                    for c in contents:
                        voice_data = {
                            'voice_id': c.voice_id,
                            'type': c.type,
                            'title': c.title,
                            'audio_url': c.audio_url
                        }
                        # 添加V2版本的voiceType信息（如果字段存在）
                        try:
                            voice_data['v2_voice_type'] = c.v2_voice_type
                        except AttributeError:
                            logging.warning(f"Voice表缺少v2_voice_type字段，请执行SQL脚本")
                            voice_data['v2_voice_type'] = None
                        result.append(voice_data)
                    
                    return JSONResponse(
                        status_code=200,
                        content={'code': 200, 'type': 2, 'data': result}
                    )
                except Exception as e:
                    logging.error(f"查询本地声音数据失败: {e}")
                    return JSONResponse(
                        status_code=500,
                        content={'error': 'Failed to retrieve local voice data'}
                    )

        elif type == 3:
            # 查询所有作品：V1作品(Job表) + V2作品(JobV2表)
            try:
                # 查询V1作品 (Job表) - 添加数据库兼容性处理
                try:
                    v1_jobs = db.query(Job).filter(Job.name_id == name_id).order_by(Job.found_time.desc()).all()
                except Exception as v1_error:
                    if "Unknown column" in str(v1_error):
                        logging.warning(f"Job表缺少字段，请执行SQL脚本：{v1_error}")
                        # 尝试查询Job表的基本字段（不包含可能缺失的字段）
                        v1_jobs = db.query(Job.id, Job.name_id, Job.job_id, Job.video_url, Job.audio_url, 
                                         Job.voice_id, Job.voice_type, Job.text, Job.title, Job.only_generate_audio,
                                         Job.image_url, Job.found_time, Job.video_time, Job.video_duration,
                                         Job.status, Job.message, Job.expire_time).filter(Job.name_id == name_id).order_by(Job.found_time.desc()).all()
                    else:
                        raise v1_error
                
                # 查询V2作品 (JobV2表) - 添加数据库兼容性处理
                try:
                    v2_jobs = db.query(JobV2).filter(JobV2.name_id == name_id).order_by(JobV2.found_time.desc()).all()
                except Exception as v2_error:
                    if "doesn't exist" in str(v2_error) or "Table" in str(v2_error):
                        logging.warning(f"JobV2表不存在，将只查询V1作品：{v2_error}")
                        v2_jobs = []
                    else:
                        raise v2_error
                
                result = []
                
                # 处理V1作品数据
                for c in v1_jobs:
                    # 检查 audio_url 是否有值，如果有值则跳过当前记录
                    audio_url = getattr(c, 'audio_url', None)
                    if audio_url:
                        continue  # 如果 audio_url 有值，则跳过该记录
                    
                    # 处理 found_time 和 video_time，如果它们为 None，不做时间加法操作
                    found_time = getattr(c, 'found_time', None)
                    video_time = getattr(c, 'video_time', None)
                    
                    # 只有当 found_time 和 video_time 都不是 None 时，才进行时间戳加8小时操作
                    if found_time is not None:
                        found_time = (datetime.fromtimestamp(found_time) + timedelta(hours=8)).timestamp()
                    if video_time is not None:
                        video_time = (datetime.fromtimestamp(video_time) + timedelta(hours=8)).timestamp()

                    result.append({
                        'name_id': getattr(c, 'name_id', None),
                        'job_id': getattr(c, 'job_id', None),
                        'video_url': getattr(c, 'video_url', None),
                        'audio_url': audio_url,  # 使用上面获取的值
                        'voice_id': getattr(c, 'voice_id', None),
                        'voice_type': getattr(c, 'voice_type', None),
                        'text': getattr(c, 'text', None),
                        'title': getattr(c, 'title', None),
                        'only_generate_audio': getattr(c, 'only_generate_audio', False),
                        'image_url': getattr(c, 'image_url', None),
                        'found_time': found_time,           
                        'video_time': video_time,           
                        'video_duration': getattr(c, 'video_duration', None),
                        'expire_time': getattr(c, 'expire_time', None),
                        'status': getattr(c, 'status', 3),
                        'message': getattr(c, 'message', ''),
                        'version': 'V1'  # 标记为V1版本
                    })
                
                # 处理V2作品数据
                for c in v2_jobs:
                    # V2作品通常不会有audio_url，所以不需要跳过
                    
                    # 处理 found_time 和 video_time
                    found_time = c.found_time
                    video_time = c.video_time
                    
                    if found_time is not None:
                        found_time = (datetime.fromtimestamp(found_time) + timedelta(hours=8)).timestamp()
                    if video_time is not None:
                        video_time = (datetime.fromtimestamp(video_time) + timedelta(hours=8)).timestamp()

                    result.append({
                        'name_id': c.name_id,
                        'job_id': c.job_id,
                        'video_url': c.video_url if c.video_url else None,
                        'audio_url': c.audio_url,  # V2版本通常为None
                        'voice_id': c.voice_id,
                        'voice_type': c.voice_type,
                        'text': c.text,
                        'title': c.title,
                        'only_generate_audio': c.only_generate_audio,
                        'image_url': c.image_url,
                        'found_time': found_time,           
                        'video_time': video_time,           
                        'video_duration': c.video_duration,
                        'expire_time': c.expire_time,
                        'status': c.status,
                        'message': c.message,
                        'version': 'V2',  # 标记为V2版本
                        'original_video_url': c.original_video_url,  # V2特有字段
                        'external_video_url': c.external_video_url   # V2特有字段
                    })
                
                # 按found_time降序排序（合并V1和V2数据后重新排序）
                result.sort(key=lambda x: x['found_time'] if x['found_time'] is not None else 0, reverse=True)
                
                return JSONResponse(status_code=200, content={'code': 200, 'type': 3, 'data': result})
                
            except Exception as e:
                logging.error(f"查询作品数据失败: {e}")
                return JSONResponse(
                    status_code=500,
                    content={'error': 'Failed to retrieve job data'}
                )

        elif type == 4:
            # 仅查询V2作品 (JobV2表)
            try:
                contents = db.query(JobV2).filter(JobV2.name_id == name_id).order_by(JobV2.found_time.desc()).all()
                
                result = []
                for c in contents:
                    # 处理 found_time 和 video_time
                    found_time = c.found_time
                    video_time = c.video_time
                    
                    if found_time is not None:
                        found_time = (datetime.fromtimestamp(found_time) + timedelta(hours=8)).timestamp()
                    if video_time is not None:
                        video_time = (datetime.fromtimestamp(video_time) + timedelta(hours=8)).timestamp()

                    result.append({
                        'name_id': c.name_id,
                        'job_id': c.job_id,
                        'video_url': c.video_url if c.video_url else None,
                        'audio_url': c.audio_url,
                        'voice_id': c.voice_id,
                        'voice_type': c.voice_type,
                        'text': c.text,
                        'title': c.title,
                        'only_generate_audio': c.only_generate_audio,
                        'image_url': c.image_url,
                        'found_time': found_time,           
                        'video_time': video_time,           
                        'video_duration': c.video_duration,
                        'expire_time': c.expire_time,
                        'status': c.status,
                        'message': c.message,
                        'version': 'V2',
                        'original_video_url': c.original_video_url,
                        'external_video_url': c.external_video_url
                    })

                return JSONResponse(status_code=200, content={'code': 200, 'type': 4, 'data': result})
                
            except Exception as e:
                logging.error(f"查询V2作品数据失败: {e}")
                return JSONResponse(
                    status_code=500,
                    content={'error': 'Failed to retrieve V2 job data'}
                )

        else:
            return JSONResponse(status_code=400, content={'error': 'Invalid type parameter'})

    except Exception as e:
        logging.error(f"Error retrieving user content: {e}")
        return JSONResponse(status_code=500, content={'error': 'Internal server error'})

# 查询指定用户作品完成状态
@router.get("/user/task")
async def get_user_task(
    job_id: str = Query(..., description="User's job_id"),
    db: Session = Depends(get_db)
):
    try:

        # 查询 Job 表
        contents = db.query(Job).filter(Job.job_id == job_id).all()
        result = [
            {
                'name_id': c.name_id,
                'job_id': c.job_id,
                'video_url': c.video_url if c.video_url else None,
                'audio_url': c.audio_url,
                'voice_id': c.voice_id,
                'voice_type': c.voice_type,
                'text': c.text,
                'title': c.title,
                'only_generate_audio': c.only_generate_audio,
                'image_url': c.image_url,
                'found_time': c.found_time,           
                'video_time': c.video_time,           
                'video_duration': c.video_duration    
            } for c in contents
        ]
        return JSONResponse(status_code=200, content={'code': 200, 'data': result})
        

    except Exception as e:
        logging.error(f"Error retrieving user content: {e}")
        return JSONResponse(status_code=500, content={'error': 'Internal server error'})

# 查询所有用户信息的接口
@router.get("/users/all")
async def get_all_users_content(
    name_id: str = Query("-1", description="Name ID, -1 for all users, -2 for specific query"),
    page: bool = Query(False, description="Pagination flag"),
    Query_time: Optional[int] = Query(None, description="Start timestamp for query"),
    end_time: Optional[int] = Query(None, description="End timestamp for query"),
    db: Session = Depends(get_db)
):
    try:
        if name_id == "-1":
            # 查询所有用户
            users = db.query(User).all()
            result = []

            for user in users:
                user_data = {
                    'name_id': user.name_id,
                    'digital_humans': [],
                    'voice_clones': [],
                    'created_works': []
                }

                # 查询用户的数字人 (Video 表)
                videos = db.query(Video).filter(Video.name_id == user.name_id).all()
                for video in videos:
                    user_data['digital_humans'].append({
                        'id': video.id,
                        'video_url': video.video_url,
                        'title': video.title,
                        'time': video.time
                    })

                # 查询用户的声音克隆 (Voice 表)
                voices = db.query(Voice).filter(Voice.name_id == user.name_id).all()
                for voice in voices:
                    user_data['voice_clones'].append({
                        'id': voice.id,
                        'voice_id': voice.voice_id,
                        'type': voice.type,
                        'voice_type': voice.voice_type,
                        'title': voice.title,
                        'audio_url': voice.audio_url,
                        'v2_voice_type': voice.v2_voice_type  # 添加V2版本的voiceType信息
                    })

                # 查询用户创建的作品 (Job 表)
                jobs = db.query(Job).filter(Job.name_id == user.name_id).all()
                for job in jobs:
                    user_data['created_works'].append({
                        'id': job.id,
                        'job_id': job.job_id,
                        'video_url': job.video_url,
                        'audio_url': job.audio_url,
                        'voice_id': job.voice_id,
                        'voice_type': job.voice_type,
                        'text': job.text,
                        'title': job.title,
                        'only_generate_audio': job.only_generate_audio,
                        'image_url': job.image_url,
                        'found_time': job.found_time,
                        'video_time': job.video_time,
                        'video_duration': job.video_duration,
                        'expire_time': job.expire_time,
                        'status': job.status,
                        'message': job.message
                    })

                result.append(user_data)

            return JSONResponse(status_code=200, content={'code': 200, 'data': result})

        elif name_id == "-2":
            # 确定查询的时间范围
            if not Query_time:
                return JSONResponse(status_code=400, content={'error': 'Query_time is required'})
            
            query_start = Query_time
            query_end = end_time if end_time is not None else int(datetime.utcnow().timestamp())

            # 查询指定时间范围内的所有已完成的作品
            jobs = db.query(Job).filter(
                Job.found_time >= query_start,
                Job.found_time <= query_end
            ).all()
            
            # 查询指定时间范围内的所有数字人
            digital_humans = db.query(Video).filter(
                Video.time >= query_start,
                Video.time <= query_end
            ).all()

            # 修复：查询指定时间范围内的所有声音克隆
            timbre_cloning = db.query(Voice).filter(
                Voice.time >= query_start,
                Voice.time <= query_end
            ).all()

            audio_duration_total = 0
            video_duration_total = 0
            digital_humans_total = len(digital_humans) 
            timbre_cloning_total = len(timbre_cloning)  # 新增：声音克隆总数
            user_stats = {}

            for job in jobs:
                if job.video_duration:
                    duration = int(job.video_duration) + 1
                    
                    if job.only_generate_audio:
                        audio_duration_total += duration
                    else:
                        video_duration_total += duration

                    # 统计每个用户的使用情况
                    if job.name_id not in user_stats:
                        user_stats[job.name_id] = {
                            'name_id': job.name_id,
                            'audio_count': 0,
                            'video_count': 0,
                            'works': []
                        }
                    
                    user_stats[job.name_id]['works'].append({
                        'job_id': job.job_id,
                        'type': 'audio' if job.only_generate_audio else 'video',
                        'duration': duration,
                        'title': job.title,
                        'found_time': job.found_time
                    })
                    
                    if job.only_generate_audio:
                        user_stats[job.name_id]['audio_count'] += 1
                    else:
                        user_stats[job.name_id]['video_count'] += 1

            weighted_audio_duration = audio_duration_total * 2
            weighted_video_duration = video_duration_total * 10
            total_points = weighted_audio_duration + weighted_video_duration

            users_list = list(user_stats.values())

            # 计算作品总数(所有job_ids的数量)
            total_jobs = sum(len(user['works']) for user in users_list)

            response_data = {
                'summary': {
                    'audio_duration_total': weighted_audio_duration,
                    'video_duration_total': weighted_video_duration,
                    'audio_count_total': audio_duration_total,
                    'video_count_total': video_duration_total,
                    'digital_humans_total': digital_humans_total,  # 数字人总数
                    'timbre_cloning_total': timbre_cloning_total,  # 新增：声音克隆总数
                    'total_duration': total_points,
                    'total_unique_users': len(user_stats),
                    'total_jobs': total_jobs,
                    'query_period': {
                        'start_time': query_start,
                        'end_time': query_end
                    }
                },
                'user_details': users_list
            }

            return JSONResponse(status_code=200, content={'code': 200, 'data': response_data})

        else:
            return JSONResponse(status_code=400, content={'error': 'Invalid parameters'})

    except Exception as e:
        logging.error(f"Error retrieving all users' content: {e}")
        return JSONResponse(status_code=500, content={'error': 'Internal server error'})

